home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 7 / Amiga Format AFCD07 (Dec 1996, Issue 91).iso / serious / shareware / programming / aros / graphics / driver_x11.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-13  |  9.6 KB  |  447 lines

  1. #include <X11/Xlib.h>
  2. #include <X11/cursorfont.h>
  3.  
  4. #define DEBUG_FreeMem 1
  5.  
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <exec/memory.h>
  9. #include <clib/exec_protos.h>
  10. #include <graphics/rastport.h>
  11. #include <graphics/gfxbase.h>
  12. #include <graphics/text.h>
  13. #include <clib/graphics_protos.h>
  14. #include <clib/aros_protos.h>
  15. #include "graphics_intern.h"
  16.  
  17. #define static    /* nothing */
  18.  
  19. static Display         * sysDisplay;
  20. static int           sysScreen;
  21. static Cursor           sysCursor;
  22. static struct TextAttr sysTA;
  23.  
  24. #ifndef SYSFONTNAME
  25. #   define SYSFONTNAME    "topaz.font"
  26. #endif
  27.  
  28. /* Table which links TextAttr with X11 font names */
  29. struct FontTable
  30. {
  31.     struct TextAttr ta;
  32.     char      * name;
  33. }
  34. AROSFontTable[] =
  35. {
  36.     { { "topaz.font", 8, FS_NORMAL, FPF_ROMFONT }, "8x13bold" },
  37.     { { "topaz.font", 13, FS_NORMAL, FPF_ROMFONT }, "8x13bold" },
  38.     { { "helvetica.font", 11, FS_NORMAL, FPF_DISKFONT }, "-adobe-helvetica-medium-r-normal--11-*-100-100-*-*-iso8859-1" },
  39.     { { "helvetica.font", 12, FS_NORMAL, FPF_DISKFONT }, "-adobe-helvetica-medium-r-normal--12-*-100-100-*-*-iso8859-1" },
  40.     { { "helvetica.font", 14, FS_NORMAL, FPF_DISKFONT }, "-adobe-helvetica-medium-r-normal--14-*-100-100-*-*-iso8859-1" },
  41. };
  42.  
  43. static const char * sysColName[] = {
  44.     "grey70",
  45.     "black",
  46.     "white",
  47.     "orange",
  48.     NULL
  49. };
  50.  
  51. static long sysCMap[] = { 0, 0, 0, 0, };
  52. static unsigned long sysPlaneMask;
  53.  
  54. struct ETextFont
  55. {
  56.     struct TextFont etf_Font;
  57.     XFontStruct     etf_XFS;
  58. };
  59.  
  60.  
  61. int driver_init (struct GfxBase * GfxBase)
  62. {
  63.     char * displayName;
  64.     Colormap cm;
  65.     XColor xc;
  66.     XColor fg, bg;
  67.     short t;
  68.     short depth;
  69.  
  70.     if (!(displayName = getenv ("DISPLAY")) )
  71.     displayName = ":0.0";
  72.  
  73.     if (!(sysDisplay = XOpenDisplay (displayName)) )
  74.     {
  75.     fprintf (stderr, "Cannot open display %s\n", displayName);
  76.     return False;
  77.     }
  78.  
  79.     sysScreen = DefaultScreen (sysDisplay);
  80.  
  81.     depth = DisplayPlanes (sysDisplay, sysScreen);
  82.     cm = DefaultColormap (sysDisplay, sysScreen);
  83.  
  84.     sysPlaneMask = 0;
  85.  
  86.     for (t=0; sysColName[t]; t++)
  87.     {
  88.     if (depth == 1)
  89.     {
  90.         sysCMap[t] = !(t & 1) ?
  91.             WhitePixel(sysDisplay, sysScreen) :
  92.             BlackPixel(sysDisplay, sysScreen);
  93.     }
  94.     else
  95.     {
  96.         if (XParseColor (sysDisplay, cm, sysColName[t], &xc))
  97.         {
  98.         if (!XAllocColor (sysDisplay, cm, &xc))
  99.         {
  100.             fprintf (stderr, "Couldn't allocate color %s\n",
  101.                 sysColName[t]);
  102.             sysCMap[t] = !(t & 1) ?
  103.                 WhitePixel(sysDisplay, sysScreen) :
  104.                 BlackPixel(sysDisplay, sysScreen);
  105.         }
  106.  
  107.         sysCMap[t] = xc.pixel;
  108.  
  109.         if (t == 0)
  110.             bg = xc;
  111.         else if (t == 1)
  112.             fg = xc;
  113.         }
  114.         else
  115.         {
  116.         fprintf (stderr, "Couldn't get color %s\n", sysColName[t]);
  117.         }
  118.     }
  119.  
  120.     sysPlaneMask |= sysCMap[t];
  121.     }
  122.  
  123.     sysCursor = XCreateFontCursor (sysDisplay, XC_xterm);
  124.     XRecolorCursor (sysDisplay, sysCursor, &fg, &bg);
  125.  
  126.     return True;
  127. }
  128.  
  129. int driver_open (struct GfxBase * GfxBase)
  130. {
  131.     struct TextFont * def;
  132.  
  133.     if (!GfxBase->DefaultFont)
  134.     {
  135.     sysTA.ta_Name  = (STRPTR)SYSFONTNAME;
  136.     sysTA.ta_YSize = 8;
  137.     sysTA.ta_Style = FS_NORMAL;
  138.     sysTA.ta_Flags = 0;
  139.  
  140.     def = OpenFont (&sysTA);
  141.  
  142.     if (!def)
  143.     {
  144.         fprintf (stderr, "Cannot open font %s; trying fixed\n",
  145.             SYSFONTNAME);
  146.  
  147.         sysTA.ta_Name = (STRPTR)"fixed";
  148.         def = OpenFont (&sysTA);
  149.  
  150.         if (!def)
  151.         {
  152.         fprintf (stderr, "Cannot open font\n");
  153.         return False;
  154.         }
  155.     }
  156.  
  157.     GfxBase->DefaultFont = def;
  158.     sysTA.ta_YSize = def->tf_YSize;
  159.     }
  160.  
  161.     GfxBase->DefaultFont->tf_Accessors ++;
  162.  
  163.     return True;
  164. }
  165.  
  166. void driver_close (struct GfxBase * GfxBase)
  167. {
  168.     GfxBase->DefaultFont->tf_Accessors --;
  169.  
  170.     return;
  171. }
  172.  
  173. void driver_expunge (struct GfxBase * GfxBase)
  174. {
  175.     CloseFont (GfxBase->DefaultFont);
  176.  
  177.     return;
  178. }
  179.  
  180. GC GetGC (struct RastPort * rp)
  181. {
  182.     return (GC) rp->longreserved[0];
  183. }
  184.  
  185. int GetXWindow (struct RastPort * rp)
  186. {
  187.     return (int) rp->longreserved[1];
  188. }
  189.  
  190. void SetGC (struct RastPort * rp, GC gc)
  191. {
  192.     rp->longreserved[0] = (IPTR)gc;
  193. }
  194.  
  195. void SetXWindow (struct RastPort * rp, int win)
  196. {
  197.     rp->longreserved[1] = (IPTR)win;
  198. }
  199.  
  200. Display * GetSysDisplay (void)
  201. {
  202.     return sysDisplay;
  203. }
  204.  
  205. int GetSysScreen (void)
  206. {
  207.     return sysScreen;
  208. }
  209.  
  210. void driver_SetAPen (struct RastPort * rp, unsigned long pen)
  211. {
  212.     pen &= 3L;
  213.  
  214.     XSetForeground (sysDisplay, GetGC (rp), sysCMap[pen]);
  215. }
  216.  
  217. void driver_SetBPen (struct RastPort * rp, unsigned long pen)
  218. {
  219.     pen &= 3L;
  220.  
  221.     XSetBackground (sysDisplay, GetGC (rp), sysCMap[pen]);
  222. }
  223.  
  224. void driver_SetDrMd (struct RastPort * rp, unsigned long mode)
  225. {
  226.     if (mode & COMPLEMENT)
  227.     XSetFunction (sysDisplay, GetGC(rp), GXxor);
  228.     else
  229.     XSetFunction (sysDisplay, GetGC(rp), GXcopy);
  230. }
  231.  
  232. void driver_RectFill (struct RastPort * rp, long x1, long y1, long x2, long y2)
  233. {
  234.     if (rp->DrawMode & COMPLEMENT)
  235.     {
  236.     ULONG pen;
  237.  
  238.     pen = ((ULONG)(rp->FgPen)) & 3L;
  239.  
  240.     XSetForeground (sysDisplay, GetGC (rp), sysPlaneMask);
  241.  
  242.     XFillRectangle (sysDisplay, GetXWindow (rp), GetGC (rp),
  243.         x1, y1, x2-x1+1, y2-y1+1);
  244.  
  245.     XSetForeground (sysDisplay, GetGC (rp), sysCMap[pen]);
  246.     }
  247.     else
  248.     XFillRectangle (sysDisplay, GetXWindow (rp), GetGC (rp),
  249.         x1, y1, x2-x1+1, y2-y1+1);
  250. }
  251.  
  252. #define SWAP(a,b)       { a ^= b; b ^= a; a ^= b; }
  253. #define ABS(x)          ((x) < 0 ? -(x) : (x))
  254.  
  255. void driver_ScrollRaster (struct RastPort * rp, long dx, long dy,
  256.     long x1, long y1, long x2, long y2, struct GfxBase * GfxBase)
  257. {
  258.     long w, h, x3, y3, x4, y4, _dx_, _dy_;
  259.     long apen = rp->FgPen;
  260.  
  261.     if (!dx && !dy) return;
  262.  
  263.     if (x2 < x1) SWAP (x1,x2)
  264.     if (y2 < y1) SWAP (y1,y2)
  265.  
  266.     _dx_ = ABS(dx);
  267.     _dy_ = ABS(dy);
  268.  
  269.     x3 = x1 + _dx_;
  270.     y3 = y1 + _dy_;
  271.  
  272.     x4 = x2 - _dx_ +1;
  273.     y4 = y2 - _dy_ +1;
  274.  
  275.     w = x2 - x3 +1;
  276.     h = y2 - y3 +1;
  277.  
  278.     SetAPen (rp, rp->BgPen);
  279.  
  280.     if (dx <= 0) {
  281.     if (dy <= 0) {
  282.         XCopyArea (sysDisplay,GetXWindow(rp),GetXWindow(rp),GetGC(rp),
  283.             x1, y1, w, h, x3, y3);
  284.  
  285.         if (_dy_) XClearArea (sysDisplay,GetXWindow(rp),
  286.             x1, y1, w+_dx_, _dy_, FALSE);
  287.  
  288.         if (_dx_) XClearArea (sysDisplay,GetXWindow(rp),
  289.             x1, y1, _dx_, h, FALSE);
  290.  
  291.     } else { /* dy > 0 */
  292.         XCopyArea (sysDisplay,GetXWindow(rp),GetXWindow(rp),GetGC(rp),
  293.             x1, y3, w, h, x3, y1);
  294.  
  295.         XClearArea (sysDisplay,GetXWindow(rp),
  296.             x1, y4, w+_dx_, _dy_, FALSE);
  297.  
  298.         if (_dx_) XClearArea (sysDisplay,GetXWindow(rp),
  299.             x1, y1, _dx_, h, FALSE);
  300.     }
  301.     } else { /* dx > 0 */
  302.     if (dy <= 0) {
  303.         XCopyArea (sysDisplay,GetXWindow(rp),GetXWindow(rp),GetGC(rp),
  304.             x3, y1, w, h, x1, y3);
  305.  
  306.         if (_dy_) XClearArea (sysDisplay,GetXWindow(rp),
  307.             x1, y1, w+_dx_, _dy_, FALSE);
  308.  
  309.         XClearArea (sysDisplay,GetXWindow(rp),
  310.             x4, y3, _dx_, h, FALSE);
  311.     } else { /* dy > 0 */
  312.         XCopyArea (sysDisplay,GetXWindow(rp),GetXWindow(rp),GetGC(rp),
  313.             x3, y3, w, h, x1, y1);
  314.  
  315.         XClearArea (sysDisplay,GetXWindow(rp),
  316.             x1, y4, w+_dx_, _dy_, FALSE);
  317.  
  318.         XClearArea (sysDisplay,GetXWindow(rp),
  319.             x4, y1, _dx_, h, FALSE);
  320.     }
  321.     }
  322.  
  323.     SetAPen (rp, apen);
  324. }
  325.  
  326. void driver_Text (struct RastPort * rp, char * string, long len,
  327.         struct GfxBase * GfxBase)
  328. {
  329.     if (rp->DrawMode & JAM2)
  330.     XDrawImageString (sysDisplay, GetXWindow(rp), GetGC(rp), rp->cp_x,
  331.         rp->cp_y, string, len);
  332.     else
  333.     XDrawString (sysDisplay, GetXWindow(rp), GetGC(rp), rp->cp_x,
  334.         rp->cp_y, string, len);
  335.  
  336.     rp->cp_x += TextLength (rp, string, len);
  337. }
  338.  
  339. WORD driver_TextLength (struct RastPort * rp, char * string, long len)
  340. {
  341.     struct ETextFont * etf;
  342.  
  343.     etf = (struct ETextFont *)rp->Font;
  344.  
  345.     return XTextWidth (&etf->etf_XFS, string, len);
  346. }
  347.  
  348. void driver_Move (struct RastPort * rp, long x, long y)
  349. {
  350.     return;
  351. }
  352.  
  353. void driver_Draw (struct RastPort * rp, long x, long y)
  354. {
  355.     XDrawLine (sysDisplay, GetXWindow(rp), GetGC(rp),
  356.         rp->cp_x, rp->cp_y,
  357.         x, y);
  358. }
  359.  
  360. void driver_WritePixel (struct RastPort * rp, long x, long y)
  361. {
  362.     XDrawPoint (sysDisplay, GetXWindow(rp), GetGC(rp),
  363.         x, y);
  364. }
  365.  
  366. void driver_SetRast (struct RastPort * rp, unsigned long color)
  367. {
  368.     XClearArea (sysDisplay, GetXWindow(rp),
  369.         0, 0,
  370.         1000, 1000,
  371.         FALSE);
  372. }
  373.  
  374. void driver_SetFont (struct RastPort * rp, struct ETextFont * font)
  375. {
  376.     if (GetGC(rp))
  377.     XSetFont (sysDisplay, GetGC(rp), font->etf_XFS.fid);
  378.  
  379.     rp->Font       = (struct TextFont *)font;
  380.     rp->TxWidth    = font->etf_Font.tf_XSize;
  381.     rp->TxHeight   = font->etf_Font.tf_YSize;
  382.     rp->TxBaseline = font->etf_Font.tf_Baseline;
  383. }
  384.  
  385. struct TextFont * driver_OpenFont (struct TextAttr * ta,
  386.     struct GfxBase * GfxBase)
  387. {
  388.     struct ETextFont * tf;
  389.     XFontStruct      * xfs;
  390.     int t;
  391.  
  392.     if (!(tf = AllocMem (sizeof (struct ETextFont), MEMF_ANY)) )
  393.     return (NULL);
  394.  
  395.     xfs = NULL;
  396.  
  397.     for (t=0; t<sizeof(AROSFontTable)/sizeof(AROSFontTable[0]); t++)
  398.     {
  399.     if (AROSFontTable[t].ta.ta_YSize == ta->ta_YSize
  400.         && !STRICMP (AROSFontTable[t].ta.ta_Name, ta->ta_Name)
  401.     )
  402.     {
  403.         xfs = XLoadQueryFont (sysDisplay, AROSFontTable[t].name);
  404.         break;
  405.     }
  406.     }
  407.  
  408.     if (!xfs)
  409.     {
  410.     FreeMem (tf, sizeof (struct ETextFont));
  411.     return (NULL);
  412.     }
  413.  
  414.     tf->etf_XFS = *xfs;
  415.  
  416.     tf->etf_Font.tf_YSize = tf->etf_XFS.max_bounds.ascent +
  417.             tf->etf_XFS.max_bounds.descent;
  418.     tf->etf_Font.tf_XSize = tf->etf_XFS.max_bounds.rbearing -
  419.             tf->etf_XFS.min_bounds.lbearing;
  420.     tf->etf_Font.tf_Baseline = tf->etf_XFS.ascent;
  421.     tf->etf_Font.tf_LoChar = tf->etf_XFS.min_char_or_byte2;
  422.     tf->etf_Font.tf_HiChar = tf->etf_XFS.max_char_or_byte2;
  423.  
  424.     if (!tf->etf_Font.tf_XSize || !tf->etf_Font.tf_YSize)
  425.     {
  426.     XUnloadFont (sysDisplay, tf->etf_XFS.fid);
  427.     FreeMem (tf, sizeof (struct ETextFont));
  428.     return (NULL);
  429.     }
  430.  
  431.     return (struct TextFont *)tf;
  432. }
  433.  
  434. void driver_CloseFont (struct ETextFont * tf, struct GfxBase * GfxBase)
  435. {
  436.     if (!tf->etf_Font.tf_Accessors)
  437.     {
  438.     XUnloadFont (sysDisplay, tf->etf_XFS.fid);
  439.     FreeMem (tf, sizeof (struct ETextFont));
  440.     }
  441. }
  442.  
  443. void driver_InitRastPort (struct RastPort * rp, struct GfxBase * GfxBase)
  444. {
  445. }
  446.  
  447.